package com.blog.cmrpersonalblog.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.blog.cmrpersonalblog.dto.role.requset.RoleCreateRequest;
import com.blog.cmrpersonalblog.dto.role.requset.RoleQueryRequest;
import com.blog.cmrpersonalblog.dto.role.requset.RoleResponse;
import com.blog.cmrpersonalblog.dto.role.requset.RoleUpdateRequest;
import com.blog.cmrpersonalblog.entity.SysRole;
import com.blog.cmrpersonalblog.entity.SysPermission;
import com.blog.cmrpersonalblog.mapper.SysRoleMapper;
import com.blog.cmrpersonalblog.service.SysRoleService;
import com.blog.cmrpersonalblog.service.SysRolePermissionService;
import com.blog.cmrpersonalblog.service.SysUserRoleService;
import jakarta.annotation.Resource;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 系统角色服务实现类
 */
@Service
public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> implements SysRoleService {

   @Resource
    private SysRolePermissionService sysRolePermissionService;

   @Resource
    private SysUserRoleService sysUserRoleService;

    @Override
    public SysRole getRoleByRoleKey(String roleKey) {
        return baseMapper.selectRoleByRoleKey(roleKey);
    }

    @Override
    public List<SysPermission> getPermissionsByRoleId(Long roleId) {
        return baseMapper.selectPermissionsByRoleId(roleId);
    }

    @Override
    public List<SysRole> getEnabledRoles() {
        return baseMapper.selectEnabledRoles();
    }

    @Override
    public List<SysRole> getRolesByUserIdWithPermissions(Long userId) {
        return baseMapper.selectRolesByUserIdWithPermissions(userId);
    }

    @Override
    public boolean canDeleteRole(Long roleId) {
        int userCount = baseMapper.countUsersByRoleId(roleId);
        return userCount == 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean assignPermissions(Long roleId, List<Long> permissionIds) {
        try {
            return sysRolePermissionService.assignPermissionsToRole(roleId, permissionIds);
        } catch (Exception e) {
            throw new RuntimeException("分配权限失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean removeAllPermissions(Long roleId) {
        try {
            return sysRolePermissionService.removeAllPermissionsFromRole(roleId);
        } catch (Exception e) {
            throw new RuntimeException("移除权限失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean createRole(RoleCreateRequest createRequest) {
        try {
            // 检查角色标识是否已存在
            if (existsRoleKey(createRequest.getRoleKey(), null)) {
                throw new RuntimeException("角色标识已存在");
            }

            // 创建角色
            SysRole role = new SysRole();
            BeanUtils.copyProperties(createRequest, role);
            role.setCreateTime(LocalDateTime.now());
            role.setUpdateTime(LocalDateTime.now());

            boolean saveResult = save(role);
            if (!saveResult) {
                throw new RuntimeException("创建角色失败");
            }

            // 分配权限
            if (createRequest.getPermissionIds() != null && !createRequest.getPermissionIds().isEmpty()) {
                sysRolePermissionService.assignPermissionsToRole(role.getId(), createRequest.getPermissionIds());
            }

            return true;
        } catch (Exception e) {
            throw new RuntimeException("创建角色失败：" + e.getMessage(), e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateRole(RoleUpdateRequest updateRequest) {
        try {
            // 检查角色是否存在
            SysRole existingRole = getById(updateRequest.getRoleId());
            if (existingRole == null) {
                throw new RuntimeException("角色不存在");
            }

            // 更新角色信息（只更新非null字段）
            SysRole role = new SysRole();
            role.setId(updateRequest.getRoleId());
            role.setUpdateTime(LocalDateTime.now());
            role.setUpdateBy(updateRequest.getUpdateBy());

            // 只更新非null的字段
            if (updateRequest.getRoleName() != null) {
                role.setRoleName(updateRequest.getRoleName());
            }
            if (updateRequest.getDescription() != null) {
                role.setDescription(updateRequest.getDescription());
            }
            if (updateRequest.getStatus() != null) {
                role.setStatus(updateRequest.getStatus());
            }

            boolean updateResult = updateById(role);
            if (!updateResult) {
                throw new RuntimeException("更新角色失败");
            }

            // 更新权限分配
            if (updateRequest.getPermissionIds() != null) {
                sysRolePermissionService.assignPermissionsToRole(updateRequest.getRoleId(), updateRequest.getPermissionIds());
            }

            return true;
        } catch (Exception e) {
            throw new RuntimeException("更新角色失败：" + e.getMessage(), e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteRole(Long roleId) {
        try {
            // 检查角色是否可以删除
            if (!canDeleteRole(roleId)) {
                throw new RuntimeException("角色正在被用户使用，无法删除");
            }

            // 删除角色权限关联
            sysRolePermissionService.removeAllPermissionsFromRole(roleId);

            // 删除角色
            return removeById(roleId);
        } catch (Exception e) {
            throw new RuntimeException("删除角色失败：" + e.getMessage(), e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteRoles(List<Long> roleIds) {
        try {
            if (roleIds == null || roleIds.isEmpty()) {
                return true;
            }

            // 检查所有角色是否可以删除
            for (Long roleId : roleIds) {
                if (!canDeleteRole(roleId)) {
                    throw new RuntimeException("角色ID " + roleId + " 正在被用户使用，无法删除");
                }
            }

            // 删除角色权限关联
            sysRolePermissionService.removePermissionsByRoleIds(roleIds);

            // 删除角色
            return removeByIds(roleIds);
        } catch (Exception e) {
            throw new RuntimeException("批量删除角色失败：" + e.getMessage(), e);
        }
    }

    @Override
    public IPage<RoleResponse> getRoleList(RoleQueryRequest queryRequest) {
        try {
            Page<SysRole> page = new Page<>(queryRequest.getCurrent(), queryRequest.getSize());

            LambdaQueryWrapper<SysRole> queryWrapper = new LambdaQueryWrapper<>();

            // 角色标识模糊查询
            if (StringUtils.hasText(queryRequest.getRoleKey())) {
                queryWrapper.like(SysRole::getRoleKey, queryRequest.getRoleKey());
            }

            // 角色名称模糊查询
            if (StringUtils.hasText(queryRequest.getRoleName())) {
                queryWrapper.like(SysRole::getRoleName, queryRequest.getRoleName());
            }

            // 状态精确查询
            if (StringUtils.hasText(queryRequest.getStatus())) {
                queryWrapper.eq(SysRole::getStatus, queryRequest.getStatus());
            }

            // 动态排序
            String sortField = queryRequest.getSafeSortField();
            String sortOrder = queryRequest.getSafeSortOrder();

            // 根据排序字段和方向设置排序
            switch (sortField) {
                case "id":
                    if ("asc".equalsIgnoreCase(sortOrder)) {
                        queryWrapper.orderByAsc(SysRole::getId);
                    } else {
                        queryWrapper.orderByDesc(SysRole::getId);
                    }
                    break;
                case "role_key":
                    if ("asc".equalsIgnoreCase(sortOrder)) {
                        queryWrapper.orderByAsc(SysRole::getRoleKey);
                    } else {
                        queryWrapper.orderByDesc(SysRole::getRoleKey);
                    }
                    break;
                case "role_name":
                    if ("asc".equalsIgnoreCase(sortOrder)) {
                        queryWrapper.orderByAsc(SysRole::getRoleName);
                    } else {
                        queryWrapper.orderByDesc(SysRole::getRoleName);
                    }
                    break;
                case "status":
                    if ("asc".equalsIgnoreCase(sortOrder)) {
                        queryWrapper.orderByAsc(SysRole::getStatus);
                    } else {
                        queryWrapper.orderByDesc(SysRole::getStatus);
                    }
                    break;
                case "create_time":
                    if ("asc".equalsIgnoreCase(sortOrder)) {
                        queryWrapper.orderByAsc(SysRole::getCreateTime);
                    } else {
                        queryWrapper.orderByDesc(SysRole::getCreateTime);
                    }
                    break;
                case "update_time":
                    if ("asc".equalsIgnoreCase(sortOrder)) {
                        queryWrapper.orderByAsc(SysRole::getUpdateTime);
                    } else {
                        queryWrapper.orderByDesc(SysRole::getUpdateTime);
                    }
                    break;
                default:
                    // 默认按ID升序
                    queryWrapper.orderByAsc(SysRole::getId);
                    break;
            }

            IPage<SysRole> rolePageResult = page(page, queryWrapper);

            // 转换为响应DTO
            IPage<RoleResponse> responsePageResult = new Page<>(rolePageResult.getCurrent(), rolePageResult.getSize(), rolePageResult.getTotal());
            List<RoleResponse> responseList = rolePageResult.getRecords().stream()
                    .map(this::convertToRoleResponse)
                    .collect(Collectors.toList());
            responsePageResult.setRecords(responseList);

            return responsePageResult;
        } catch (Exception e) {
            throw new RuntimeException("查询角色列表失败", e);
        }
    }

    @Override
    public RoleResponse getRoleDetail(Long roleId) {
        try {
            SysRole role = getById(roleId);
            if (role == null) {
                return null;
            }
            return convertToRoleResponse(role);
        } catch (Exception e) {
            throw new RuntimeException("查询角色详情失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateRoleStatus(Long roleId, String status, String updateBy) {
        try {
            SysRole role = new SysRole();
            role.setId(roleId);
            role.setStatus(status);
            role.setUpdateBy(updateBy);
            role.setUpdateTime(LocalDateTime.now());
            return updateById(role);
        } catch (Exception e) {
            throw new RuntimeException("更新角色状态失败", e);
        }
    }

    @Override
    public boolean existsRoleKey(String roleKey, Long excludeId) {
        try {
            LambdaQueryWrapper<SysRole> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(SysRole::getRoleKey, roleKey);
            if (excludeId != null) {
                queryWrapper.ne(SysRole::getId, excludeId);
            }
            return count(queryWrapper) > 0;
        } catch (Exception e) {
            throw new RuntimeException("检查角色标识失败", e);
        }
    }

    @Override
    public List<RoleResponse> getAllRolesForSelect() {
        try {
            LambdaQueryWrapper<SysRole> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(SysRole::getStatus, "0"); // 只查询正常状态的角色
            queryWrapper.orderByAsc(SysRole::getRoleKey);

            List<SysRole> roles = list(queryWrapper);
            return roles.stream()
                    .map(this::convertToRoleResponse)
                    .collect(Collectors.toList());
        } catch (Exception e) {
            throw new RuntimeException("查询角色列表失败", e);
        }
    }

    /**
     * 转换为角色响应DTO
     */
    private RoleResponse convertToRoleResponse(SysRole role) {
        RoleResponse response = new RoleResponse();
        BeanUtils.copyProperties(role, response);

        // 获取角色权限
        List<SysPermission> permissions = getPermissionsByRoleId(role.getId());
        response.setPermissions(permissions);

        // 获取使用该角色的用户数量
        List<Long> userIds = sysUserRoleService.getUserIdsByRoleId(role.getId());
        response.setUserCount(userIds.size());

        // 设置是否可以删除
        response.setCanDelete(userIds.isEmpty());

        return response;
    }
}
